home *** CD-ROM | disk | FTP | other *** search
- /* dirutil.c - MS-DOS directory reading routines
- *
- * Bdale Garbee, N3EUA, Dave Trulli, NN2Z, and Phil Karn, KA9Q
- * Directory sorting by Mike Chepponis, K3MC
- * New version using regs.h by Russell Nelson.
- * Rewritten for Turbo-C 2.0 routines by Phil Karn, KA9Q 25 March 89
- *
- * Changed commas to dots for European use :-) - DB3FL.910216
- *
- */
-
- #include <stdio.h>
- #include <dir.h>
- #include <dos.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include "global.h"
- #include "dirutil.h"
- #include "commands.h"
- #include "files.h"
-
- #ifdef XXX
- static int getdir_nosort __ARGS((char *path,int full,FILE *file));
- #endif
-
- #define REGFILE (FA_HIDDEN|FA_SYSTEM|FA_DIREC)
-
- #define insert_ptr(list,new) (new->next = list,list = new)
-
- struct dirsort {
- struct dirsort *next;
- struct ffblk de;
- };
- #define NULLSORT (struct dirsort *)0
-
- /*
- * Return a string with commas every 3 positions.
- * the original string is replace with the string with commas.
- * The caller must be sure that there is enough room for the resultant
- * string.
- *
- * k3mc 4 Dec 87
- *
- * Changed to dots instead of commas for european use - DB3FL.910216
- *
- */
- static void near
- commas(dest)
- char *dest;
- {
- char *src, *core; /* Place holder for malloc */
- unsigned cc; /* The comma counter */
-
- unsigned len = strlen(dest);
- /* Make a copy, so we can muck around */
- core = src = strxdup(dest);
-
- cc = (len-1) % 3 + 1; /* Tells us when to insert a comma */
-
- while(*src != '\0'){
- *dest++ = *src++;
- if( ((--cc) == 0) && *src ) {
- *dest++ = '.';
- cc = 3;
- }
- }
- xfree(core);
- *dest = '\0';
- }
-
- static int near
- fncmp(char *a,char *b)
- {
- int i;
-
- for(;;){
- if (*a == '.')
- return -1;
- if (*b == '.')
- return 1;
- if ((i = *a - *b++) != 0)
- return i;
- if (!*a++)
- return -1;
- }
- }
-
- /* Provide additional information only on DIR */
- static void near
- print_free_space(file, n, d)
- FILE *file;
- int n, d;
- {
- unsigned long free_bytes, total_bytes;
- char s_free[15], s_total[15];
- struct dfree dtable;
- unsigned long bpcl;
-
- /* Find disk free space */
- getdfree(d,&dtable);
-
- bpcl = dtable.df_bsec * dtable.df_sclus;
- free_bytes = dtable.df_avail * bpcl;
- total_bytes = dtable.df_total * bpcl;
-
- sprintf(s_free,"%ld",free_bytes);
- commas(s_free);
- sprintf(s_total,"%ld",total_bytes);
- commas(s_total);
-
- fprintf(file,"%s%d file(s). %s bytes free. Disk size %s bytes.\n",
- (n & 1) ? "\n" : "",n,s_free,s_total);
- }
-
- static void near
- format_fname_full(file, sbuf, full, n)
- FILE *file;
- struct ffblk *sbuf;
- int full, n;
- {
- char line_buf[50]; /* for long dirlist */
- char cbuf[20]; /* for making line_buf */
-
- strcpy(cbuf,sbuf->ff_name);
- if (sbuf->ff_attrib & FA_DIREC) strcat(cbuf, "/");
- if (full) {
- /* Long form, give other info too */
- sprintf(line_buf,"%-13s",cbuf);
- if(sbuf->ff_attrib & FA_DIREC)
- strcat(line_buf," ");/* 11 spaces */
- else {
- sprintf(cbuf,"%ld",sbuf->ff_fsize);
- commas(cbuf);
- sprintf(line_buf+strlen(line_buf),"%10s ",cbuf);
- }
- sprintf(line_buf+strlen(line_buf),"%2d:%02d %2d.%02d.%02d%s",
- (sbuf->ff_ftime >> 11) & 0x1f, /* hour */
- (sbuf->ff_ftime >> 5) & 0x3f, /* minute */
- (sbuf->ff_fdate ) & 0x1f, /* day */
- (sbuf->ff_fdate >> 5) & 0xf, /* month */
- (sbuf->ff_fdate >> 9) + 80, /* year */
- (n & 1) ? " " : "\n");
- fputs(line_buf,file);
- } else {
- fprintf(file,"%s\n",cbuf);
- }
- }
-
- /* find the first or next file and lowercase it. */
- static int near
- nextname(command, name, sbuf)
- int command;
- char *name;
- struct ffblk *sbuf;
- {
- int found = (command == 0) ? findfirst(name,sbuf,REGFILE) : findnext(sbuf);
-
- if((found = found == 0) != 0)
- strlwr(sbuf->ff_name);
-
- return found;
- }
-
- /* fix up the filename so that it contains the proper wildcard set */
- static char * near
- wildcardize(path)
- char *path;
- {
- struct ffblk sbuf;
- static char ourpath[64];
- int i;
-
- /* Root directory is a special case */
- if(path == NULLCHAR)
- path = "/*.*";
- else {
- i = strlen(path);
- i--;
- if(path[i] == '\\' || path[i] == '/')
- strcat(path,"*.*");
- else if(path[i] == ':')
- strcat(path,"/*.*");
- }
-
- /* if they gave the name of a subdirectory, append \*.* to it */
- if (nextname(0, path, &sbuf)
- && (sbuf.ff_attrib & FA_DIREC)
- && !nextname(1, path, &sbuf)) {
- /* if there isn't enough room, give up -- it's invalid anyway */
- if (strlen(path) + 4 > 63) return path;
- strcpy(ourpath, path);
- strcat(ourpath, "\\*.*");
- return ourpath;
- }
-
- return path;
- }
-
- /* Create a directory listing in a temp file and return the resulting file
- * descriptor. If full == 1, give a full listing; else return just a list
- * of names.
- */
- FILE *
- dir(path,full)
- char *path;
- int full;
- {
- FILE *fp;
-
- if((fp = temp_file(0,1)) != NULLFILE){
- getdir(path,full,fp);
- rewind(fp);
- }
- return fp;
- }
-
- /* wildcard filename lookup */
- int
- filedir(name,times,ret_str)
- char *name;
- int times;
- char *ret_str;
- {
- static struct ffblk sbuf;
- int rval = (times == 0) ? findfirst(name,&sbuf,REGFILE) : findnext(&sbuf);
-
- strcpy(ret_str,(rval == -1) ? "\0" : sbuf.ff_name);
-
- return rval;
- }
-
- /* do a directory list to the stream full = 0 -> short form, 1 is long */
- int
- getdir(path,full,file)
- char *path;
- int full;
- FILE *file;
- {
- struct ffblk sbuf;
- int command = 0, n = 0, d = 0;
- struct dirsort *head = NULLSORT, *here, *new, *next;
-
- path = wildcardize(path);
-
- for(;;){
- if (!nextname(command, path, &sbuf))
- break;
- command = 1; /* Got first one already... */
- if (sbuf.ff_name[0] == '.') /* drop "." and ".." */
- continue;
-
- new = (struct dirsort *)mxallocw(sizeof(struct dirsort));
- new->de = sbuf; /* Copy contents of directory entry struct */
-
- /* insert it into the list */
- if (!head || fncmp(new->de.ff_name, head->de.ff_name) < 0) {
- insert_ptr(head, new);
- } else {
- struct dirsort *this;
- for (this = head;
- this->next != NULLSORT;
- this = this->next)
- if (fncmp(new->de.ff_name, this->next->de.ff_name) < 0)
- break;
- insert_ptr(this->next, new);
- }
- } /* infinite FOR loop */
-
- for (here = head; here; here = here->next)
- format_fname_full(file,&here->de,full,++n);
-
- /* Give back all the memory we temporarily needed... */
- while (head != NULLSORT) {
- next = head->next;
- xfree(head);
- head = next;
- }
-
- if(path[1] == ':')
- d = (toupper(path[0])) - 64;
- if(full)
- print_free_space(file, n, d);
-
- return 0;
- }
-
- /* Change working directory */
- int
- docd(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- char dirname[128], *s;
-
- if(argc < 2) {
- if(getcwd(dirname,128) != NULLCHAR) {
- while((s = strchr(dirname,'\\')) != NULLCHAR)
- *s = '/';
- tprintf("%s\n",dirname);
- }
- } else if(chdir(argv[1]) == -1)
- tprintf("Can't change to %s: %s\n",argv[1],sys_errlist[errno]);
- return 0;
- }
-
- /* List directory to console */
- int
- dodir(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- char tmpname[L_tmpnam+1];
- FILE *fp;
-
- char *path = (argc < 2) ? "*.*" : argv[1];
- char **margv = (char **)cxallocw(2,sizeof(char *));
-
- tmpnam(tmpname);
- if((fp = open_file(tmpname,WRITE_TEXT,0,1)) == NULLFILE)
- return -1;
- getdir(path,1,fp);
- fclose(fp);
- margv[1] = strxdup(tmpname);
- domore(2,margv,p);
- xfree(margv[1]);
- xfree(margv);
- unlink(tmpname);
- return 0;
- }
-
- /* Delete file/s */
- int
- dodelete(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- int i;
-
- for(i = 1; i < argc; i++)
- if(unlink(argv[i]) == -1)
- tprintf("Can't delete %s: %s\n",argv[i],sys_errlist[errno]);
- return 0;
- }
-
- /* Rename file */
- int
- dorename(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- if(rename(argv[1],argv[2]) == -1)
- tprintf("Can't rename %s to %s: %s\n",argv[1],argv[2],sys_errlist[errno]);
- return 0;
- }
-
- /* Create directory */
- int
- domkd(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- int i;
-
- for(i = 1; i < argc; i++)
- if(mkdir(argv[i]) == -1)
- tprintf("Can't make %s: %s\n",argv[i],sys_errlist[errno]);
- return 0;
- }
-
- /* Remove directory */
- int
- dormd(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- int i;
-
- for(i = 1; i < argc; i++)
- if(rmdir(argv[i]) == -1)
- tprintf("Can't delete %s: %s\n",argv[i],sys_errlist[errno]);
- return 0;
- }
-
- #ifdef XXX
- static int
- getdir_nosort(path,full,file)
- char *path;
- int full;
- FILE *file;
- {
- struct ffblk sbuf;
- int command = 0, n = 0; /* Number of directory entries */
-
- path = wildcardize(path);
-
- while(nextname(command, path, &sbuf)){
- command = 1; /* Got first one already... */
- if (sbuf.ff_name[0] == '.') /* drop "." and ".." */
- continue;
- format_fname_full(file, &sbuf, full, ++n);
- }
- if(full)
- print_free_space(file, n, 0);
- return 0;
- }
- #endif
-